7 segment display

Contenido

Como manejar un pantalla de 7 segmentos con varios digitos.

El modulo que uso es el 5641BS, las conexiones son las siguientes:

Este modulo tiene las conexiones hechas con Ánodo común, hay otra versión con Cátodo común la 5641AS, en este las conexiones son las siguientes:

Los segmentos asociados con cada pin son los siguientes:

Circuito

El circuito en el simulador es el siguiente:

Código

Para hacer funcionar los 4 números de la pantalla tenemos que hacer multiplexación entre ellos, al igual que en una matriz de leds

La lista de numeros es la siguiente, del 0 al 9 (1 indica segmento iluminado):

volatile uint8_t numbers[] = {
  0b00111111,
  0b00000110,
  0b01011011,
  0b01001111,
  0b01100110,
  0b01101101,
  0b01111101,
  0b00000111,
  0b01111111,
  0b01101111,
};

NOTA: El bit mas significativo es para el punto (.), este bit lo activamos en la posición que queramos despues de asignar los dígito, en el siguiente ejemplo se activa en el tercer dígito.

En este caso tenemos un ejemplo que solo va incrementando un numero y lo muestra en la pantalla, tenemos que tener en cuenta que el módulo que uso es de Ánodo común, por lo tanto para encender los segmentos usamos negativo (pin a 0) y el dígito que vamos a iluminar es controlado con positivo (pin a 1).

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

volatile uint8_t numbers[] = {
  0b00111111,
  0b00000110,
  0b01011011,
  0b01001111,
  0b01100110,
  0b01101101,
  0b01111101,
  0b00000111,
  0b01111111,
  0b01101111,
};

volatile uint8_t display[4] = {0};

volatile uint16_t count = 0;
volatile uint8_t display_iteration = 0;


ISR(TIMER0_COMPA_vect) {
      PORTD = 0xFF; //Apagamos todos los leds para evitar efecto de iluminacion fantasma en algunos leds

      PORTC = (1 << display_iteration);
      PORTD = display[display_iteration];

      display_iteration++;
      if(display_iteration == 4)
        display_iteration = 0;
}

void init_timer0(){
  TCCR0A |= (1 << WGM01);
  TCCR0B |= (1 << CS02); // Prescaler de 256
  TIMSK0 |= (1 << OCIE0A);
  OCR0A = 2; // Interrupción cada 512 microsegundos

  sei();
}


int main(void) {

    init_timer0();

    DDRC = 0b00001111;
    PORTC = 0b00001111;
    DDRD = 0b11111111;

    while(1){
      _delay_ms(10);

      //Asociamos cada digito con el numero que le corresponde, el byte se invierte (~), ya que estamos usando Anodo comun.
      display[0] = ~numbers[(count / 1000)%10];
      display[1] = ~numbers[(count / 100)%10];
      display[2] = ~numbers[(count / 10)%10];
      display[3] = ~numbers[count%10];

      display[2] &= 0b01111111; //Ponemos el punto en el tercer digito.

      count++;

      if(count == 9999)
        count = 0;
    }
}
Tags

AVR | 7 segment